package main

import (
	"log"
	"net/http"
	"time"
)

type WsSeverCallBack interface {
	OnDisConected(*WsConnection)
	OnConected(*WsConnection)
	OnDataRecv(*WsConnection, []byte)
}

type WsServer struct {
	maxConnId int64
	// 用于广播
	WsConnAll map[int64]*WsConnection
	callback  WsSeverCallBack
}

func NewWsServer() *WsServer {
	return &WsServer{
		WsConnAll: make(map[int64]*WsConnection, 1),
		maxConnId: 0,
	}
}

// 读取消息队列中的消息
func (this *WsServer) WsHandler(resp http.ResponseWriter,
	req *http.Request) {
	// 应答客户端告知升级连接为websocket
	wsSocket, err := upgrader.Upgrade(resp, req, nil)
	if err != nil {
		log.Println("升级为websocket失败", err.Error())
		return
	}
	wsSocket.SetReadLimit(40960)
	this.maxConnId++
	// TODO 如果要控制连接数可以计算，wsConnAll长度
	// 连接数保持一定数量，超过的部分不提供服务
	wsConn := &WsConnection{
		wsSocket:          wsSocket,
		inChan:            make(chan *wsMessage, 50),
		outChan:           make(chan *wsMessage, 50),
		closeChan:         make(chan byte),
		isClosed:          false,
		id:                this.maxConnId,
		lastHeartBeatTime: time.Now(),
		needHeartBeat:     false,
		server:            this,
	}
	this.WsConnAll[this.maxConnId] = wsConn
	log.Println("当前在线人数", len(this.WsConnAll))
	if this.callback != nil {
		this.callback.OnConected(wsConn)
	}
	// 处理器,发送定时信息，避免意外关闭
	go wsConn.processLoop(this)
	// 读协程
	go wsConn.wsReadLoop(this)
	// 写协程
	go wsConn.wsWriteLoop(this)
}

func (this *WsServer) StartServer(server string) {
	this.WsConnAll = make(map[int64]*WsConnection)
	http.HandleFunc("/ws", this.WsHandler)
	http.ListenAndServe(server, nil)
}

func (this *WsServer) DelConection(conn *WsConnection) {
	delete(this.WsConnAll, conn.id)
}
func (this *WsServer) SetProto(callback WsSeverCallBack) {
	this.callback = callback
}
